import { useRef, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';

import { useRequest } from 'ahooks';
import { Button, Form, FormProps, Input } from 'antd';

import CodeInput from '@/components/code-input';

import { store } from '@/store';

import { emailReg, mobileReg } from '@/config/rule';
import { ClientType, LoginType } from '@/enum';
import { securityLogin, securityPublicKey } from '@/services/base/denglumokuaidenglujiekou';
import {
  codeSendEmailCode,
  codeSendMobileCode
} from '@/services/base/yanzhengmamokuaifasongyanzhengmajiekou';
import { orgUserInfoSelfPassword } from '@/services/base/yonghuguanliyonghumimaxiangguanjiekou';
import { encryptRSA } from '@/utils/encrypt';

import Panel from '../panel';

type FormValues = {
  username: string;
  code: string;
  password: string;
  rePassword: string;
};

const Page: React.FC = () => {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const [form] = Form.useForm();
  const captchaVerification = useRef('');
  const [codeSuccess, setCodeSuccess] = useState(false);
  const updatePassword = useRequest(
    async ({ username, password: _password, code }: FormValues) => {
      if (!codeSuccess) {
        store.app?.message.error('请先获取验证码');

        return;
      }

      // 登录
      const isMobile = mobileReg.test(username);
      const isEmail = emailReg.test(username);

      if (!isMobile && !isEmail) {
        store.app?.message.error('请输入正确的邮箱或者手机号');

        return;
      }

      // 加密密码
      const publicKey = (await securityPublicKey()).data;
      const password = await encryptRSA(_password, async () => publicKey);

      const query = {
        clientType: ClientType.web,
        captchaVerification: captchaVerification.current,
        password,
        code
      } as {
        loginType: LoginType;
        clientType: ClientType;
        password: string;
        captchaVerification: string;
        code: string;
        mobile?: string;
        email?: string;
      };

      if (isMobile) {
        query.loginType = LoginType.mobile;
        query.mobile = username;
      } else if (isEmail) {
        query.email = username;
        query.loginType = LoginType.email;
      }

      const token = (await securityLogin(query as unknown as string)).data!;

      // 修改密码
      await orgUserInfoSelfPassword(
        {
          password: password,
          checkPassword: password
        } as unknown as ArgumentsType<typeof orgUserInfoSelfPassword>[0],
        {
          headers: {
            token: token
          }
        }
      );

      // 获取用户信息
      const userInfo = await store.getUserInfoByToken(token);

      if (!userInfo) {
        store.app?.message.error('获取用户信息失败');

        return;
      }

      store.app?.message.success('修改密码成功');

      localStorage.setItem('token', token);
      const redirect = searchParams.get('redirect') || '/';
      navigate(redirect);

      return userInfo;
    },
    {
      manual: true
    }
  );

  const onFinish: FormProps<FormValues>['onFinish'] = (values) => {
    updatePassword.run(values);
  };

  return (
    <Panel
      corner={{
        to: '/user/login',
        children: '登录'
      }}
      title="找回密码"
    >
      <Form<FormValues>
        form={form}
        onFinish={onFinish}
        size="large"
        variant="filled"
        disabled={updatePassword.loading}
      >
        <Form.Item
          name="username"
          rules={[
            { required: true, message: '请输入邮箱或者手机号' },
            {
              validator: async (_, value) => {
                // 不对空值校验
                if (value === '' || value === null || typeof value === 'undefined') {
                  return;
                }

                if (mobileReg.test(value)) {
                  return;
                }

                if (emailReg.test(value)) {
                  return;
                }

                return Promise.reject(new Error('请输入正确的邮箱或者手机号!'));
              }
            }
          ]}
        >
          <Input placeholder="请输入邮箱或者手机号" allowClear autoComplete="new-password" />
        </Form.Item>

        <Form.Item dependencies={['username']} noStyle>
          {({ getFieldValue }) => {
            const isMobile = mobileReg.test(getFieldValue('username'));
            const isEmail = emailReg.test(getFieldValue('username'));

            return (
              <Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}>
                <CodeInput
                  getCode={async (captcha) => {
                    captchaVerification.current = captcha;
                    const { username } = await form.validateFields(['username']);

                    await (isMobile
                      ? codeSendMobileCode({ mobile: username })
                      : codeSendEmailCode({ email: username }));
                  }}
                  onCodeSuccess={() => {
                    setCodeSuccess(true);
                  }}
                  buttonDisabled={!isMobile && !isEmail}
                  placeholder="请输入验证码"
                  allowClear
                  autoComplete="new-password"
                />
              </Form.Item>
            );
          }}
        </Form.Item>

        {codeSuccess && (
          <>
            <Form.Item
              name="password"
              rules={[{ required: true, message: '请输入新密码' }]}
              hasFeedback
            >
              <Input.Password placeholder="请输入新密码" allowClear autoComplete="new-password" />
            </Form.Item>

            <Form.Item
              name="rePassword"
              dependencies={['password']}
              hasFeedback
              rules={
                [
                  { required: true, message: '请确认新密码' },
                  ({ getFieldValue }) => ({
                    validator(_, value) {
                      if (!value || getFieldValue('password') === value) {
                        return Promise.resolve();
                      }

                      return Promise.reject(new Error('两次输入的密码不一致!'));
                    }
                  })
                ]!
              }
            >
              <Input.Password placeholder="请确认新密码" allowClear autoComplete="new-password" />
            </Form.Item>
          </>
        )}

        <Button
          type="primary"
          block
          htmlType="submit"
          loading={updatePassword.loading}
          disabled={updatePassword.loading}
        >
          {!codeSuccess ? '下一步' : '重置密码'}
        </Button>
      </Form>
    </Panel>
  );
};

export default Page;
